package logTest

import (
	"errors"
	"fmt"
	"path/filepath"
	"runtime"
	"strings"
	"time"
)

type LogI interface {
	Debug(message ...interface{})
	Info(message ...interface{})
	Warn(message ...interface{})
	Error(message ...interface{})
	Panic(message ...interface{})

	Println(level string, message ...interface{})
	Close()
}

var defaultLevel int

type text struct {
	fileName string
	line     int
	fullPath string
	funcName string
}

func SetLevel(def int) {
	defaultLevel = def
}

var logLevel = map[string]int{
	"DEBUG": 1,
	"INFO":  2,
	"WARN":  3,
	"ERROR": 4,
	"PANIC": 5,
}

func callerInfo(skip int) (ctx *text, err error) {
	pc, file, line, ok := runtime.Caller(skip)
	if !ok {
		return nil, errors.New("error  during runtime.Callers")
	}

	funcInfo := runtime.FuncForPC(pc)
	if funcInfo == nil {
		return nil, errors.New("error during runtime.FuncForPC")
	}

	funcName := funcInfo.Name()
	if strings.HasPrefix(funcName, ".") {
		funcName = funcName[strings.Index(funcName, "."):]
	}

	ctx = &text{
		funcName: filepath.Base(funcName),
		line:     line,
		fullPath: file,
		fileName: filepath.Base(file),
	}

	return ctx, nil
}

func write(level string, message interface{}) string {
	if logLevel[level] <= defaultLevel {
		return ""
	}
	skip := 3
	ctx, err := callerInfo(skip)
	if err != nil {
		fmt.Println("log println err! " + time.Now().Format("2006-01-02 15:04:05") + " Error: " + err.Error())
	}
	msg := fmt.Sprintf("[%s] %s [%s:%v] %v", level, time.Now().Format("2006-01-02 15:04:05"), ctx.fileName, ctx.line, message)
	fmt.Println(msg)
	return msg
}
